# -*- coding: utf-8 -*-
"""
@Time    : 2020/11/20
@Author  : xinghen
@File    : nh_gra_utils.py
"""
import pandas as pd
import numpy as np
from numpy import *
import matplotlib.pyplot as plt


# 从硬盘读取数据进入内存


class NhGraUtils():

    def __init__(self):
        pass

    def read_data(self):
        """
        read data from excel
        :return:
        """
        jx_df = pd.read_excel("data_1.xlsx", index_col=0, header=0)
        # print(jx_df)
        return jx_df

    def normal_data(self, df, normal_flag):
        """
        normalize data frame
        :param df:
        :param normal_flag: min or max
        :return:
        """
        if normal_flag == 0:
            df = df.append(pd.Series(df.max(axis=0), name="normal"))
        elif normal_flag == 1:
            df = df.append(pd.Series(df.min(axis=0), name="normal"))

        new_data_frame = pd.DataFrame(index=df.index)
        columns = df.columns.tolist()
        for c in columns:
            d = df[c]
            MAX = d.max()
            MIN = d.min()
            if normal_flag == 0:
                new_data_frame[c] = (1 - (d - MIN) / MAX).tolist()
            elif normal_flag == 1:
                new_data_frame[c] = (1 - (d - MIN) / MAX).tolist()
        return new_data_frame

    def cal_gra(self, df, v_weight):
        """
        calculate GRA result
        :param df:
        :return:
        """
        # data sub normal data
        df = df.fillna(1)
        normal_row = df.loc['normal']
        new_data_frame = pd.DataFrame(df)
        for inx_name in df.index:
            new_data_frame.loc[inx_name, :] = (df.loc[inx_name] - normal_row).abs()

        # calculate GRA 0.5/(d+0.5)
        gra_matrix = new_data_frame.drop(labels='normal', axis=0).pipe(lambda df: 0.5 / (df + 0.5))
        gra_result = gra_matrix.apply(lambda x: x * v_weight.iloc[:,0], axis=1).apply(lambda x: sum(x), axis=1) * 100
        return gra_result.sort_values(ascending=False)

    #############################################################################################################
    # # 无量纲化
    # def dimensionlessProcessing(self, df):
    #     new_data_frame = pd.DataFrame(index=df.index)
    #     columns = df.columns.tolist()
    #     for c in columns:
    #         d = df[c]
    #         MAX = d.max()
    #         MIN = d.min()
    #         MEAN = d.mean()
    #         new_data_frame[c] = ((d - MEAN) / (MAX - MIN)).tolist()
    #     return new_data_frame
    #
    # def GRA_ONE(self,gray, m=0):
    #     # 读取为df格式
    #     gray = self.dimensionlessProcessing(gray)
    #     # 标准化
    #     std = gray.iloc[:, m]  # 为标准要素
    #     gray.drop(str(m), axis=1, inplace=True)
    #     ce = gray.iloc[:, 0:]  # 为比较要素
    #     shape_n, shape_m = ce.shape[0], ce.shape[1]  # 计算行列
    #
    #     # 与标准要素比较，相减
    #     a = zeros([shape_m, shape_n])
    #     for i in range(shape_m):
    #         for j in range(shape_n):
    #             a[i, j] = abs(ce.iloc[j, i] - std[j])
    #
    #     # 取出矩阵中最大值与最小值
    #     c, d = amax(a), amin(a)
    #
    #     # 计算值
    #     result = zeros([shape_m, shape_n])
    #     for i in range(shape_m):
    #         for j in range(shape_n):
    #             result[i, j] = (d + 0.5 * c) / (a[i, j] + 0.5 * c)
    #
    #     # 求均值，得到灰色关联值,并返回
    #     result_list = [mean(result[i, :]) for i in range(shape_m)]
    #     result_list.insert(m, 1)
    #     return pd.DataFrame(result_list)
    #
    # def GRA(self, DataFrame):
    #     df = DataFrame.copy()
    #     list_columns = [
    #         str(s) for s in range(len(df.columns)) if s not in [None]
    #     ]
    #     df_local = pd.DataFrame(columns=list_columns)
    #     df.columns = list_columns
    #     for i in range(len(df.columns)):
    #         df_local.iloc[:, i] = self.GRA_ONE(df, m=i)[0]
    #     return df_local

    def gra(self, jx_df, optimum_flag, weights=np.array([0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125])):
        normal_df = self.normal_data(jx_df, optimum_flag)
        gra_results = self.cal_gra(normal_df, weights)
        return gra_results


if __name__ == '__main__':
    nh_alg_utils = NhGraUtils()
    jx_df = NhGraUtils().read_data()
    gra_result = nh_alg_utils.gra(jx_df, 1, np.array([1]))
    print(gra_result)
